package utility.cipher;

import java.io.ByteArrayOutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class EncryptionTest {

	private static final String[] ALGORITHMS = { "AES" };

	enum Key {
		XUNIQ(0, "hexa"), SERVER_URL(1,
		"hexa");

		private int index;
		private byte[] key;

		private Key(int index, String key) {
			this.index = index;
			this.key = toByteArray(key);
		}

		byte[] getKey() {
			return key;
		}

		int getIndex() {
			return index;
		}

		public static Key valueOf(int index) {
			Key keys[] = Key.values();
			for (Key key : keys) {
				if (key.getIndex() == index)
					return key;
			}

			new IllegalArgumentException("Unknown key index: " + index);
			return null;
		}
	}

	static String decrypt(String value) throws Exception {
		// アルゴリズムとキーの選択
		int algorithmIndex, keyIndex;
		try {
			algorithmIndex = Integer.parseInt(value.substring(0, 1));
		} catch (Exception e) {
			throw new NoSuchAlgorithmException(e.getMessage());
		}
		try {
			keyIndex = Integer.parseInt(value.substring(1, 2));
		} catch (Exception e) {
			throw new InvalidKeyException(e.getMessage());
		}

		validate(algorithmIndex, keyIndex);

		String algorithm = ALGORITHMS[algorithmIndex];
		Key key = Key.valueOf(keyIndex);

		// アルゴリズムとキーのインデックス(先頭2バイト)を除去
		value = value.substring(2);

		// 復号化
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getKey(),
				algorithm));
		String s = new String(cipher.doFinal(toByteArray(value)));
		String chuoi1 = new String(toByteArray(value));
		System.out.println("sau khi ma hoa duoc chuoi bytes: " + new String(toByteArray(value)));

		// test encrypt
		cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getKey(), algorithm));

		byte input[] = s.getBytes();
		// (3)暗号化の実施
		byte encrypted[] = cipher.doFinal(input);

		String chuoi2 = new String(encrypted);
		System.out.println("sau khi ma hoa duoc chuoi bytes (tu minh): " + new String(encrypted));
		boolean b = chuoi1.equals(chuoi2);
		System.out.println(b ? "equals" : "not equals");
		System.out.println("to hex: " + bytesToHex(encrypted));
		System.out.println(" value: " + value);
		System.out.println(bytesToHex(encrypted).equals(value) ? "euqals" : "noe eq");

		// test

		return s;
	}

	private static void validate(int algorithmIndex, int keyIndex)
			throws NoSuchAlgorithmException, InvalidKeyException {
		if (algorithmIndex < 0 || algorithmIndex >= ALGORITHMS.length)
			throw new NoSuchAlgorithmException("Invalid algorithm index.");
		try {
			Key key = Key.valueOf(keyIndex);
			if (key == null)
				throw new InvalidKeyException("Invalid key index.");
		} catch (Exception e) {
			throw new InvalidKeyException("Invalid key index.");
		}
	}

	public static void main(String[] args) throws Exception {
		String serverUrl = "http://r.af-share.jp/ad";
	/*	String enc = "encoded";

		String ret = EncryptionTest.decrypt(enc);
		System.out.println("--original--");
		System.out.println(serverUrl);
		System.out.println("decript");
		System.out.println(ret);
		EncryptionTest.Banchat(encoded);

		byte[] bytes = new byte[]{105,2,16,8,9,10,17};
		System.out.println(bytesToHex(bytes));

		String s = "69";
		System.out.println(new Integer(toByteArray(s)[0]));
		System.out.println("--encrypt--");

*/
		serverUrl = "http://d-tran.ds01.info/mysql.php";
		String ss = encript(serverUrl);
		System.out.println(ss);
		System.out.println("-- ban chat 2");
		EncryptionTest.Banchat2(ss);
		EncryptionTest.Banchat("");
	}

	public static void Banchat(String value) throws Exception {
		String algorithm = "AES";
		Cipher cipher = Cipher.getInstance(algorithm);
		Key key = Key.valueOf(1);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getKey(),
				algorithm));
		String s = new String(cipher.doFinal(toByteArray(value)));

		System.out.println("--- ban chat ---");
		System.out.println(s);


	}


	final protected static char[] hexArray = "0123456789abcdef".toCharArray();

	public static String bytesToHex(byte[] bytes) {
	    char[] hexChars = new char[bytes.length * 2];
	    for ( int j = 0; j < bytes.length; j++ ) {
	        int v = bytes[j] & 0xFF;
	        hexChars[j * 2] = hexArray[v >>> 4];
	        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
	    }
	    return new String(hexChars);
	}

	public static byte[] toByteArray(String value) {
		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
		for (int i = 0; i < value.length(); i += 2) {
			int b = Integer.parseInt(value.substring(i, i + 2), 16);
			bytes.write(b);
		}
		return bytes.toByteArray();
	}

	public static String encript(String value) throws Exception {
		String algorithm = "AES";
		Key key = Key.valueOf(1);
		// test encrypt
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getKey(), algorithm));

		// (3)暗号化の実施
		byte input[] = value.getBytes();
		byte encrypted[] = cipher.doFinal(input);

		return bytesToHex(encrypted);
	}

	public static void Banchat2(String value) throws Exception {
		String algorithm = "AES";
		Cipher cipher = Cipher.getInstance(algorithm);
		Key key = Key.valueOf(1);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getKey(),
				algorithm));
		String s = new String(cipher.doFinal(toByteArray(value)));

		System.out.println("--- ban chat ---");
		System.out.println(s);


	}

}
